/****************************************Copyright (c)****************************************************
**
**
**
**
**---------------------------------------File Info--------------------------------------------------------
** File name:           sysPara.h
** Last modified Date:  2020-6-1
** Last Version:        V0.0
** Descriptions:        系统参数类型定义
**
**--------------------------------------------------------------------------------------------------------
** Created by:          刘毅
** Created date:        2020-6-1
** Version:             V0.0
** Descriptions:
**
*********************************************************************************************************/
#ifndef __SYS_PARA_H
#define __SYS_PARA_H

#include <string.h>                                         //for memset...
#include <stdbool.h>                                        //for bool
#include <rtthread.h>

#define SYS_HW_VER          "V3.2"                          //硬件版本
#define SYS_SW_VER          "V1.6"                          //软件版本

#define MIN_MONIT_CUR       0.8f                            //最小监视电流，小于此电流则强制归零【常规0.5A】【高精度0.05A】
#define MIN_CHG_CUR         1.5f                            //最小充电检测电流，大于此电流判断为充电【常规1.5A】【高精度0.1A】
#define MIN_DCHG_CUR        -1.5f                           //最小放电检测电流，大于此电流判断为放电【常规-1.5A】【高精度-0.1A】

#define APP_ADDRSS          0x08020000                      //应用程序地址
#define VECT_OFFSET         0x00020000                      //中断向量偏移量

#define MIN_CELL            8                               //系统最少支持电芯数量(AFE硬件决定)
#define MAX_CELL            16                              //系统最多支持电芯数量(硬件决定)
#define MAX_CELL_NTC        4                               //系统最多支持NTC传感器数量(硬件决定)
#define MAX_CUR_LIMIT       12                              //最大限流值(电感、MOS管、续流二极管决定)

#define MIN_NUM(x, y)       ((x) < (y) ? (x) : (y))
#define MAX_NUM(x, y)       ((x) > (y) ? (x) : (y))


#pragma pack(1)                                             //n字节对齐

//=======事件相关定义------------------------------------------------------------------------------------
typedef enum
{
    EV_NONE         = 0,                                    //没有事件
    EV_OCCUR        = 1,                                    //已经发生，等待确认
    EV_RESUME       = 2,                                    //已经恢复，等待确认
    EV_CONFIRM      = 3,                                    //已经确认
}eventStatus_t;

typedef union
{
    rt_uint64_t all;
    struct
    {
        rt_uint64_t pack_CHG_OV            : 2;                //bit1..0--->总体充电过压
        rt_uint64_t pack_DCHG_UV           : 2;                //bit3..2--->总体放电欠压
        rt_uint64_t pack_CHG_OC_1          : 2;                //bit5..4--->充电一次过流
        rt_uint64_t pack_CHG_OC_2          : 2;                //bit7..6--->充电二次过流
        rt_uint64_t pack_DCHG_OC_1         : 2;                //bit9..8--->放电一次过流
        rt_uint64_t pack_DCHG_OC_2         : 2;                //bit11..10--->放电二次过流

        rt_uint64_t cell_CHG_OV            : 2;                //bit13..12->电芯充电过压
        rt_uint64_t cell_DCHG_UV           : 2;                //bit15..14->电芯放电欠压
        rt_uint64_t cell_ODV               : 2;                //bit17..16->电芯压差过大

        rt_uint64_t cell_CHG_HT            : 2;                //bit19..18->电芯充电高温
        rt_uint64_t cell_CHG_LT            : 2;                //bit21..20->电芯充电低温
        rt_uint64_t cell_DCHG_HT           : 2;                //bit23..22->电芯放电高温
        rt_uint64_t cell_DCHG_LT           : 2;                //bit25..24->电芯放电低温
        rt_uint64_t cell_ODT               : 2;                //bit27..26->电芯温差过大

        rt_uint64_t mos_CHG_HT             : 2;                //bit29..28->MOS充电高温
        rt_uint64_t mos_DCHG_HT            : 2;                //bit31..30->MOS放电高温

        rt_uint64_t env_CHG_HT             : 2;                //bit33..32->电芯充电高温
        rt_uint64_t env_CHG_LT             : 2;                //bit35..34->电芯充电低温
        rt_uint64_t env_DCHG_HT            : 2;                //bit37..36->电芯放电高温
        rt_uint64_t env_DCHG_LT            : 2;                //bit39..38->电芯放电低温

        rt_uint64_t pack_SC                : 2;                //bit41..40->短路
        rt_uint64_t antitheft              : 2;                //bit43..42->防盗
        rt_uint64_t low_SOC                : 2;                //bit45..44->SOC过低
        rt_uint64_t chg_INV                : 2;                //bit47..46->充电机反接
        rt_uint64_t mosFault               : 2;                //bit49..48->MOS损坏

        rt_uint64_t                        : 0;                //未名空洞，自动计算保留位
    };
}eventFlag_t;

//=======系统状态定义结构--------------------------------------------------------------------------------
typedef struct
{
    float voltage[MAX_CELL];
    float maxVoltage;
    float minVoltage;
    rt_uint8_t maxVoltageId;
    rt_uint8_t minVoltageId;
}cellVoltage_t;

typedef struct
{
    float temperature[MAX_CELL_NTC];
    float maxTemperature;
    float minTemperature;
    rt_uint8_t maxTemperatureId;
    rt_uint8_t minTemperatureId;
}cellTemperature_t;

typedef enum
{
    CUR_IDLE        = 0,                                    //空闲状态(不充不放)
    CUR_CHG         = 1,                                    //充电状态
    CUR_DCHG        = 2,                                    //放电状态
}currentStatus_t;

typedef struct
{
    cellVoltage_t cellVoltage;                              //电芯电压
    cellTemperature_t cellTemperature;                      //电芯温度

    eventFlag_t warningEvent;                               //警告事件标志组
    eventFlag_t protectEvent;                               //保护事件标志组
    eventStatus_t clEvent;                                  //限流事件
    currentStatus_t currentStatus;                          //电流状态

    float packVoltage;                                      //总电压V
    float current;                                          //电流
    float soc;                                              //荷电状态SOC
    float soh;                                              //健康状态SOH
    float mosTemperature;                                   //MOS管温度
    float envTemperature;                                   //环境温度
    float inclination;                                      //电池倾斜角度

    bool cFet;                                              //充电MOS状态
    bool dFet;                                              //放电MOS状态
    bool limitCharging;                                     //限流充电状态
    bool balancing;                                         //均衡中

    bool ntcFault;                                          //温度传感器损坏
    bool buzzerBeep;                                        //蜂鸣器鸣叫状态
    bool heating;                                           //加热器状态

    struct
    {
        rt_uint8_t relay_1             : 1;                    //继电器1状态
        rt_uint8_t relay_2             : 1;                    //继电器2状态
        rt_uint8_t                     : 2;                    //预留
        rt_uint8_t input_1             : 1;                    //输入节点1状态
        rt_uint8_t input_2             : 1;                    //输入节点2状态
        rt_uint8_t                     : 2;                    //预留
    }dryContact;                                            //干接点状态
    struct
    {
        rt_uint8_t vrlaParalleling     : 1;                    //铅酸并入状态
        rt_uint8_t                     : 3;                    //预留
        rt_uint8_t lithiumParalleling  : 1;                    //锂电并入状态
        rt_uint8_t                     : 3;                    //预留
    }batteryMix;                                            //铅锂混用状态
}sysStatus_t;

//-------------------------------------------------------------------------------------------------------
//=======参数类型结构------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
typedef struct
{
    float value;
    float minValue;
    float maxValue;
}valueDetail_t;

typedef struct
{
    struct
    {
        valueDetail_t valueDetail;                                  //值
        rt_uint32_t delayMS;                                        //达到值后的动作延迟时间(毫秒)
    }threshold;                                                     //阈值
    struct
    {
        valueDetail_t valueDetail;                                  //值
        rt_uint32_t delayMS;                                        //达到值后的动作延迟时间(毫秒)
    }resume;                                                        //恢复值
}paraValue_t;                                                       //参数值

//状态机定义
typedef enum
{
    STATE_INIT,
    STATE_WAIT_THRESHOLD_CONFIRM,
    STATE_WAIT_RESUME_CONFIRM
} state_t;

//事件触发时的回调
typedef void (*event_callback_t)(void);


#define NUM_PARAMETERS 48            //保护告警各24个
typedef enum
{
    CHARGE_PACK_VOLTAGE               = 0x0001,
    CHARGE_CELL_VOLTAGE               = 0x0002,
    CHARGE_CURRENT_1                  = 0x0003,
    CHARGE_CURRENT_2                  = 0x0004,
    CHARGE_CELL_HIGH_TEMPERTURE       = 0x0005,
    CHARGE_CELL_LOW_TEMPERTURE        = 0x0006,
    CHARGE_ENV_HIGH_TEMPERTURE        = 0x0007,
    CHARGE_ENV_LOW_TEMPERTURE         = 0x0008,
    CHARGE_MOS_HIGH_TEMPERTURE        = 0x0009,
    CHARGE_CELL_VOLTAGE_DIFFER        = 0x000A,
    CHARGE_CELL_TEMPER_DIFFER         = 0x000B,
    CHARGE_HIGH_SOC                   = 0x000C,
    DISCHARGE_PACK_VOLTAGE            = 0x0101,
    DISCHARGE_CELL_VOLTAGE            = 0x0102,
    DISCHARGE_CURRENT_1               = 0x0103,
    DISCHARGE_CURRENT_2               = 0x0104,
    DISCHARGE_CELL_HIGH_TEMPERTURE    = 0x0105,
    DISCHARGE_CELL_LOW_TEMPERTURE     = 0x0106,
    DISCHARGE_ENV_HIGH_TEMPERTURE     = 0x0107,
    DISCHARGE_ENV_LOW_TEMPERTURE      = 0x0108,
    DISCHARGE_MOS_HIGH_TEMPERTURE     = 0x0109,
    DISCHARGE_CELL_VOLTAGE_DIFFER     = 0x010A,
    DISCHARGE_CELL_TEMPER_DIFFER      = 0x010B,
    DISCHARGE_LOW_SOC                 = 0x010C

}paraId_t;

typedef enum
{
    ALARM,
    PROTECTION
}warningType_t;

typedef struct
{
    paraId_t paraId;
    currentStatus_t currentStatus;
    warningType_t warningType;
    paraValue_t paraValue;
    rt_bool_t greater_than;  // 比较方向，TRUE 表示大于，FALSE 表示小于
}para_t;

typedef struct
{
    para_t param;
    event_callback_t threshold_cb;
    event_callback_t resume_cb;
    float current_value;
    state_t state;
    rt_timer_t timer;
    rt_bool_t greater_than;  // 比较方向，TRUE 表示大于，FALSE 表示小于
} paraContext_t;

//=======模拟前端校准------------------------------------------------------------------------------------
typedef struct
{
    struct
    {
        float mlGIM;                                        //ML5238电流采样的增益
        float mlVIMZ;                                       //ML5238电流采样的零点值
    }times_10;                                              //10倍增益校准值
    struct
    {
        float mlGIM;                                        //ML5238电流采样的增益
        float mlVIMZ;                                       //ML5238电流采样的零点值
    }times_50;                                              //10倍增益校准值
    float shunt;                                            //分流器阻值
    float chgI_50;                                          //充电50倍增益时的满程电流
    float dchgI_50;                                         //放电50倍增益时的满程电流
    bool usegGim50;                                         //使用50倍增益
    bool calibing;                                          //正在校准
}calib_t;

//=======防盗--------------------------------------------------------------------------------------------
typedef enum
{
    ATF_NONE                = 0x00,                         //不启用

    EN_PHYSIC_NOW           = 0x01,                         //立即启用物理防盗
    EN_LINK_NOW             = 0x02,                         //立即启用通信防盗
    EN_PHYSIC_LINIK_NOW     = 0x03,                         //立即启用物理防盗和通信防盗

    EN_PHYSIC_CHG           = 0x04,                         //充电后启用物理防盗
    EN_LINK_CHG             = 0x05,                         //充电后启用通信防盗
    EN_PHYSIC_LINIK_CHG     = 0x06,                         //充电后启用物理防盗和通信防盗

    IS_PHYSIC_NOW           = 0x81,                         //已经启用物理防盗
    IS_LINK_NOW             = 0x82,                         //已经启用通信防盗
    IS_PHYSIC_LINIK_NOW     = 0x83,                         //已经启用物理防盗和通信防盗

    IS_PHYSIC_CHG           = 0x84,                         //已经充电并启用物理防盗
    IS_LINK_CHG             = 0x85,                         //已经充电并启用通信防盗
    IS_PHYSIC_LINIK_CHG     = 0x86,                         //已经充电并启用物理防盗和通信防盗
}antitheftMode_t;

typedef struct
{
    antitheftMode_t mode;                                   //防盗模式
    rt_uint32_t physicDelayMS;                                 //物理防盗延迟时间
    rt_uint32_t linkDelayMS;                                   //通信防盗延时时间
}antitheft_t;                                               //防盗参数

//=======限流--------------------------------------------------------------------------------------------
typedef enum
{
    CL_DISABLE  = 0,                                        //禁能限流功能
    CL_ACTIVE   = 1,                                        //主动限流模式-->充电电流始终不能超过限流值[limitValue]
    CL_TRIG     = 2,                                        //触发(被动)限流模式-->充电电流超过触发值[trigValue]则启动限流功能，把电流限制在限流值[limitValue]以内，此模式会有退出尝试
}clMode_t;

typedef struct
{
    clMode_t mode;                                          //限流模式
    float limitValue;                                       //限流值(触发后电流被限制到limitValue工作)
    float trigValue;                                        //触发值(电流达到trigValue后触发限流)
    rt_uint32_t trigDelayMS;                                   //触发后延迟检测依然超过触发值则可以确认事件
    rt_uint32_t retryDelayMS;                                  //被动限流状态下，经过retryDelayMS则尝试切回主路
}currentLimit_t;

//=======间歇充电----------------------------------------------------------------------------------------
typedef struct
{
    bool en;                                                //开关
    float trigSoc;                                          //SOC触发值(达到此值触发间歇充电)
    rt_uint32_t trigDelayMS;                                   //触发后延迟检测依然超过触发值则可以确认事件
    rt_uint32_t intermitMS;                                    //间歇时间
}intermitChg_t;

//=======历史记录----------------------------------------------------------------------------------------
typedef union
{
    rt_uint8_t buf[sizeof(rt_uint32_t) + sizeof(sysStatus_t)];
    struct
    {
        rt_uint32_t time;                                      //每条状态记录时间unix时间戳
        sysStatus_t status;                                 //系统状态
    };
}log_t;                                                     //日志记录结构体

typedef struct
{
    bool en;                                                //开关，满足时间配置自动开启，录波结束后自动关闭
    rt_uint16_t interval;                                      //间隔时间 单位s
    rt_uint32_t startTime;                                     //录波起始时间，unix时间戳 单位s
    rt_uint32_t timeSpan;                                      //录波时长，单位s
}record_t;                                                  //定时录波参数配置

typedef struct
{
    rt_uint32_t writeAddr;                                     //入栈写地址
    rt_uint32_t readAddr;                                      //出栈读地址
    rt_uint32_t autoLogInterval;                               //自动记录模式的时间间隔
    rt_uint32_t logCapacity;                                   //log容量（存储log的总条数，所需存储空间为logCapacity*logSize字节）
    rt_uint16_t logSize;                                       //每条log所占的字节数
    bool fullFlag;                                          //满标识
    bool emptyFlag;                                         //空标识
    record_t record;                                        //定时录波参数配置
}logPara_t;

//=======均衡参数----------------------------------------------------------------------------------------
typedef struct
{
    rt_uint8_t en;                                             //均衡使能
    float volatageDiff;                                     //均衡启动压差
    float voltageAverage;                                   //均衡启动最低平均单体电压
    float minSoc;                                           //均衡启动最小SOC
}balancePara_t;

//=======功能开关参数------------------------------------------------------------------------------------
typedef struct
{
    bool sleepEn;                                           //休眠开关
    bool beepEn;                                            //蜂鸣器开关
    bool heatEn;                                            //加热开关
    bool maintainEn;                                        //维护模式开关(现场维护时MOS不能导通，以防止事故)
}functionEn_t;

//=======数值参数----------------------------------------------------------------------------------------
typedef struct
{
    rt_uint16_t cycleCount;                                    //循环次数
    rt_uint32_t underVoltage2sleepTimeS;                       //欠压休眠时间 s
    float fullCapacityAh;                                   //满充容量 Ah
    float remainCapacityAh;                                 //剩余容量 Ah
    float totalChgTimeH;                                    //总充时间 h
    float totalChgCapacityAh;                               //总充容量 Ah
    float totalChgEnergyKwh;                                //总充能量 KWh
    float totalDchgTimeH;                                   //总放时间 h
    float totalDchgCapacityAh;                              //总放容量 Ah
    float totalDchgEnergyKwh;                               //总放能量 KWh
}numerical_t;                                               //数值型参数

//=======系统参数定义结构--------------------------------------------------------------------------------
typedef struct
{
    para_t paraList[NUM_PARAMETERS];                       //告警及保护参数

    calib_t calib;                                          //校准参数
    antitheft_t antitheft;                                  //防盗参数
    currentLimit_t currentLimit;                            //限流参数
    intermitChg_t intermitChg;                              //间歇充电参数
    logPara_t logPara;                                      //历史记录参数
    balancePara_t balancePara;                              //均衡参数
    functionEn_t functionEn;                                //功能开关参数
    numerical_t numeric;                                    //数值型参数
}runPara_t;                                                 //运行参数


//=======制造参数定义结构--------------------------------------------------------------------------------
typedef struct
{
    char pcbSn[16];
    char batterySn[16];
    char model[16];

    rt_uint8_t cellNum;                                        //电芯数量(小于等于MAX_CELL)
    rt_uint8_t cellNtcNum;                                     //NTC传感器数量(小于等于MAX_CELL_NTC)
    float inclinationBase;                                  //电池倾斜角度基准
    rt_uint32_t ratedCapacityAh;                               //电池额定容量    100 Ah

}producePara_t;                                             //制造参数


//=======定制参数定义结构--------------------------------------------------------------------------------
typedef enum
{
    MB_NONE         = 0,                                    //不使用MODBUS协议
    MB_ZTE          = 1,                                    //中兴协议
    MB_GROWATT      = 2,                                    //古瑞瓦特协议
    MB_INCELL       = 3,                                    //INCELL协议
    MB_VERTIV       = 4,                                    //维谛协议
    MB_SACRED       = 5,                                    //圣阳协议
    MB_HUAWEI       = 6,                                    //华为协议
    MB_GP           = 7,                                    //GreenPole协议
    MB_VOLTRONIC    = 8,                                    //日月元协议
}modbusFirm_t;                                              //MODBUS协议厂商，用于区分协议类型

typedef struct
{
    modbusFirm_t modbusFirm;                                //MODBUS协议厂商
    bool modBus_OV_Mask;                                    //modbus屏蔽过压信息上报
    bool batteryMixEn;                                      //铅锂混合使能
    rt_uint16_t mixLiQuitTimeMin;                              //铅锂混用时预估锂电退出时间,单位分钟

}customPara_t;                                              //客户定制参数

//=======标志参数定义结构--------------------------------------------------------------------------------
typedef struct
{
    bool staelLock;                                         //防盗锁定
    rt_uint8_t programRunPartition;                            //程序运行分区 0xFF--应用程序为空，停留在bootloader中 0--主运行区  1--升级区  2--紧急恢复区

}flag_t;                                                    //系统标志

typedef union
{
    rt_uint8_t buf[sizeof(runPara_t) + sizeof(producePara_t) + sizeof(customPara_t) + sizeof(flag_t)];
    struct
    {
        runPara_t runPara;
        producePara_t producePara;
        customPara_t customPara;
        flag_t flag;
    };
}sysPara_t;                                                 //系统参数包含运行参数、制造参数和客户定制参数

typedef enum
{
    SYS_OBJ_WORKING         = 0,                            //工作中使用的参数
    SYS_OBJ_BACKUP          = 1,                            //一键ghost使用的备份参数
    SYS_OBJ_SHADOW          = 2,                            //用于程序自行修改的影子参数
    SYS_OBJ_IOT             = 3,                            //物联网配置参数
}sysParaObj_t;                                              //系统参数对象

//=======物联网参数定义结构------------------------------------------------------------------------------
typedef union
{
    rt_uint8_t buf[336];
    struct
    {
        char apn[16];                                       //APN名称，ASCII码，不足部分以0x20填充
        char apnUserName[16];                               //APN用户名，ASCII码，不足部分以0x20填充
        char apnPassword[16];                               //APN密码，ASCII码，不足部分以0x20填充
        char deviceId[32];                                  //物联网设备编码，ASCII码，不足部分以0x20填充
        char targetIPGroup[256];                            //物联网设备IP地址或域名组，多个域名或IP地址时用“;"隔开，端口号在IP地址或
    };
}iotPara_t;


#pragma pack()                                              //取消字节对齐


//=======接口数据申明------------------------------------------------------------------------------------
extern sysPara_t g_sysPara;                                 //系统参数
extern sysPara_t g_sysParaBackup;                           //系统参数备份（用于用户修改的恢复。一键ghost）
extern sysPara_t g_sysParaShadow;                           //系统参数影子（用于程序自行修改的恢复）

extern iotPara_t g_iotPara;                                 //物联网配置参数

extern const sysPara_t g_minPara;                           //系统(最小值)参数定义
extern const sysPara_t g_maxPara;                           //系统(最大值)参数定义

//=======接口函数申明------------------------------------------------------------------------------------
void SYS_SavePara(sysParaObj_t obj);
void SYS_LoadPara(bool forceFactory);
rt_uint32_t SYS_GetCompileTime(void);
void para_init(paraContext_t *ctx, const para_t *param, event_callback_t threshold_cb, event_callback_t resume_cb);
void para_update_value(paraContext_t *ctx, float new_value);

#endif // __SYS_PARA_H
/*********************************************************************************************************
**  End Of File
**  在烧写的时候是FLASH中的被占用的空间为:      Code + RO-data + RW-data
**  程序运行的时候，芯片内部RAM使用的空间为:    RW-data + ZI-data
*********************************************************************************************************/
